home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-17 | 20.7 KB | 593 lines | [TEXT/MPS ] |
- ;_________________________________________________________________________
- ;
- ; dmz.a
- ;_________________________________________________________________________
- ;
- ; DTS Code Sample
- ;
- ; ©1990 Apple Computer, Inc.
- ;
- ; 3/7/90 - 10/26/90 pvh
- ;
- ;_________________________________________________________________________
-
- PRINT PUSH,OFF ; don't print any of this stuff
-
- INCLUDE 'QuickEqu.a'
- INCLUDE 'ToolEqu.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'ATalkEqu.a'
- INCLUDE 'SysErr.a'
-
- PRINT POP ; restore the PRINT options
-
-
- ;---------------------------------------
- mySaveA5 PROC EXPORT
-
- movea.l (a7)+, a1 ; save the return address
- MOVE.L a5, -(a7) ; move current a5 onto stack
- movea.l $2C(a0), a5 ; get 'our' a5 from saved paramBlock
- jmp (a1) ; return to sender
-
- ENDP
-
- ;---------------------------------------
- myRestoreA5 PROC EXPORT
-
- movea.l (a7)+, a1 ; save the return address
- MOVE.L (a7)+, a5 ; move saved a5 back into a5
- jmp (a1) ; return to sender
-
- ENDP
-
- ;---------------------------------------
- RestoreA5 PROC EXPORT
-
- MOVE.L (a7)+, a5 ; move saved a5 back into a5
-
- ENDP
-
- ; Socket Listener Sample
- ;
- ; 3/92 Jim Luther, Apple DTS
- ;
- ; ©1992 Apple Computer, Inc.
- ;_________________________________________________________________________
-
- INCLUDE 'QuickEqu.a'
- INCLUDE 'ToolEqu.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'ATalkEqu.a'
- INCLUDE 'SysErr.a'
-
- ;
- ;
- ; Record Types
- ;
- ;_________________________________________________________________________
-
- QHdr RECORD 0
- qFlags DS.W 1
- qHead DS.L 1
- qTail DS.L 1
- ENDR
-
- PacketBuffer RECORD 0
- qLink DS.L 1
- qType DS.W 1
- buffer_Type DS.W 1 ; DDP Type
- buffer_NodeID DS.W 1 ; Destination node
- buffer_Address DS.L 1 ; Source address in AddrBlock format
- buffer_Hops DS.W 1 ; Hop count
- buffer_ActCount DS.W 1 ; length of DDP datagram
- buffer_CheckSum DS.W 1 ; Chksum error returned here (cksumErr or noErr)
- buffer_Ticks DS.W 1 ; TickCount when handler called
- buffer_Data DS.B ddpMaxData ; the DDP datagram
- ENDR
-
- ;_________________________________________________________________________
- ;
- ; Local Variables
- ;
- ;_________________________________________________________________________
-
- SL_Locals PROC
- ENTRY free_queue,used_queue,current_qelem
-
- free_queue DC.L 0 ; pointer to freeQ QHdr - initialized by InitSktListener
- used_queue DC.L 0 ; pointer to usedQ QHdr - initialized by InitSktListener
- current_qelem DC.L 0 ; pointer to current PacketBuffer record
- ; initialized by InitSktListener, then
- ; set by socket listener after every packet.
- ; NIL if no buffer is available.
- ENDP
-
- ;_________________________________________________________________________
- ;
- ; SL_DoChksum - accumulate ongoing checksum (from Inside Macintosh)
- ;
- ; Input:
- ; D1 (word) = number of bytes to checksum
- ; D3 (word) = current checksum
- ; A1 points to the bytes to checksum
- ;
- ; Return:
- ; D0 is modified
- ; D3 (word) = accumulated checksum
- ;_________________________________________________________________________
-
- SL_DoChksum PROC
- CLR.W D0 ; Clear high byte
- SUBQ.W #1,D1 ; Decrement count for DBRA
- ChksumLoop:
- MOVE.B (A1)+,D0 ; read a byte into D0
- ADD.W D0,D3 ; accumulate checksum
- ROL.W #1,D3 ; rotate left one bit
- DBRA D1,ChksumLoop ; loop if more bytes
- RTS
- ENDP
-
- ;_________________________________________________________________________
- ;
- ; SL_TheListener
- ;
- ;_________________________________________________________________________
-
- ;_________________________________________________________________________
- ;
- ; SL_TheListner - process packets received at the designated socket
- ;
- ; Input:
- ; D0 (byte) = packet's destination socket number
- ; D1 (word) = number of bytes left to read in packet
- ; A0 points to the bytes to checksum
- ; A1 points to the bytes to checksum
- ; A2 points to MPP's local variables
- ; A3 points to next free byte in Read Header Area
- ; A4 points to ReadPacket and ReadRest jump table
- ;
- ; Return:
- ; D0 is modified
- ; D3 (word) = accumulated checksum
- ;_________________________________________________________________________
- SL_TheListener PROC EXPORT
-
- WITH PacketBuffer
-
- ; get pointer to current PacketBuffer
-
- GetBuffer:
- LEA current_qelem,A3 ; get the pointer to the PacketBuffer to use
- MOVE.L (A3),A3
- MOVE.L A3,D0 ; if no PacketBuffer
- BEQ.S NoBuffer ; then ignore packet
-
- ; read rest of packet into PacketBuffer.datagramData
-
- MOVE.L D1,D3 ; read rest of packet
- LEA buffer_data(A3),A3 ; A3 = ^bufferData
- JSR 2(A4) ; ReadRest
- BEQ.S ProcessPacket ; If no error, continue
- BRA RcvRTS ; there was an error, so ignore packet
-
- ; No buffer; ignore the packet
-
- NoBuffer CLR D3 ; Set to ignore packet (buffer size = 0)
- JSR 2(A4) ; ReadRest
- BRA GetNextBuffer ; We missed this packet, but maybe there
- ; will be a buffer for the next packet…
-
- ; Process the packet you just read in.
- ; ReadRest has been called so registers A0-A3 and D0-D3 are free to use.
- ; We'll use registers this way:
- PktBuff EQU A0 ; the current PacketBuffer
- MPPLocals EQU A2 ; pointer to MPP's local variables (still set up
- ; from entry to socket listener)
- HopCount EQU D0 ; used to get the hop count
- DatagramLength EQU D1 ; used to determine the datagram length
- SourceNetAddr EQU D2 ; used to build the source network address
-
- ProcessPacket:
- LEA current_qelem,PktBuff ; PktBuff = current_qelem
- MOVE.L (PktBuff),PktBuff
-
- ; do everything that's common to both long and short DDP headers
-
- ; save tickCount in buffer_Ticks field
-
- MOVE.L Ticks,buffer_Ticks(PktBuff)
-
- ; first, clear buffer_Type and buffer_NodeID to ensure their high bytes are 0
-
- CLR.W buffer_Type(PktBuff) ; clear buffer_Type
- CLR.W buffer_NodeID(PktBuff) ; clear buffer_NodeID
-
- ; clear SourceNetAddr to prepare to build network address
-
- MOVEQ #0,SourceNetAddr ; build the network address in SourceNetAddr
-
- ; get the hop count
- MOVE.W toRHA+lapHdSz+ddpLength(MPPLocals),HopCount ; Get hop/length field
- ANDI.W #DDPHopsMask,HopCount ; Mask off the hop count bits
- LSR.W #2,HopCount ; shift hop count into low bits of high byte
- LSR.W #8,HopCount ; shift hop count into low byte
- MOVE.W HopCount,buffer_Hops(PktBuff) ; and move it into the PacketBuffer
-
- ; get the packet length (including the DDP header)
- MOVE.W toRHA+lapHdSz+ddpLength(MPPLocals),DatagramLength ; Get length field
- ANDI.W #ddpLenMask,DatagramLength ; Mask off the hop count bits
-
- ; now, find out if the DDP header is long or short
-
- MOVE.B toRHA+lapType(MPPLocals),D3 ; Get LAP type
- CMPI.B #shortDDP,D3 ; is this a long or short DDP header?
- BEQ.S IsShortHdr ; skip if short DDP header
-
- ; it's a long DDP header
-
- MOVE.B toRHA+lapHdSz+ddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP type
-
- MOVE.B toRHA+lapHdSz+ddpDstNode(MPPLocals),buffer_NodeID+1(PktBuff)
- ; get destination node from LAP header
-
- MOVE.L toRHA+lapHdSz+ddpSrcNet(MPPLocals),SourceNetAddr
- ; source network in hi word
- ; source node in lo byte
- LSL.W #8,SourceNetAddr ; shift source node up to high byte of low word
- ; get source socket from DDP header
- MOVE.B toRHA+lapHdSz+ddpSrcSkt(MPPLocals),SourceNetAddr
-
- SUB.W #ddpType+1,DatagramLength ; DatagramLength = number of bytes in datagram
- BRA.S MoveToBuffer
-
- ; checksum time…
- TST.W toRHA+lapHdSz+ddpChecksum(MPPLocals) ;Does packet have checksum?
- BEQ.S noChecksum
-
- ; Calculate checksum over DDP header
- MOVE.L DatagramLength,-(SP) ; save DatagramLength (D1)
-
- CLR D3 ; set checksum to zero
- MOVEQ #ddphSzLong-ddpDstNet,D1 ; D1 = length of header part to checksum
- ; pointer to dest network number in DDP header
- LEA toRHA+lapHdSz+ddpDstNet(MPPLocals),A1
- JSR SL_DoChksum ; checksum of DDP header part
- ; (D3 holds accumulated checksum)
-
- ; Calculate checksum over data portion (if any)
-
- MOVE.L buffer_Data(PktBuff),A1 ; pointer to datagram
- MOVE.L (SP)+,DatagramLength ; restore DatagramLength (D1)
- MOVE.L DatagramLength,-(SP) ; save DatagramLength (D1)
- ; before calling SL_DoChksum
- BEQ.S TestChecksum ; don't checksum datagram if its length = 0
- JSR SL_DoChksum ; checksum of DDP datagram part
- ; (D3 holds accumulated checksum)
-
- TestChecksum:
- MOVE.L (SP)+,DatagramLength ; restore DatagramLength (D1)
-
- ; Now make sure the checksum is OK.
-
- TST.W D3 ; is the calculated value zero?
- BNE.S NotZero ; no -- go and use it
- SUBQ.W #1,D3 ; it is 0; make it -1
-
- NotZero:
- CMP.W toRHA+lapHdSz+ddpChecksum(MPPLocals),D3
- BNE.S ChecksumErr ; Bad checksum
- MOVE.W #0,buffer_CheckSum(A0) ; no errors
- BRA.S noChecksum
- ChecksumErr:
- MOVE.W #ckSumErr,buffer_CheckSum(PktBuff) ; checksum error
-
- noChecksum:
- BRA.S MoveToBuffer
-
-
- ; it's a short DDP header
-
- IsShortHdr:
- MOVE.B toRHA+lapHdSz+sddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP type
- MOVE.B toRHA+lapDstAdr(MPPLocals),buffer_NodeID+1(PktBuff)
- ; get destination node from LAP header
- MOVE.B toRHA+lapSrcAdr(MPPLocals),SourceNetAddr ; get source node from LAP header
- LSL.W #8,SourceNetAddr ; shift src node up to high byte of low word
- MOVE.B toRHA+lapHdSz+sddpSrcSkt(MPPLocals),SourceNetAddr
- ; get source socket from short DDP header
- SUB.W #sddpType+1,DatagramLength ; DatagramLength = number of bytes in datagram
-
- MoveToBuffer:
- MOVE.L SourceNetAddr,buffer_Address(PktBuff)
- ;move source network address into PacketBuffer
- MOVE.W DatagramLength,buffer_ActCount(PktBuff)
- ; move datagram length into PacketBuffer
-
-
- ; Now that we're done with the PacketBuffer, enqueue it into the usedQ and get
- ; another buffer from the freeQ for the next packet.
-
- LEA used_queue,A1 ; A1 = ^used_queue
- MOVE.L (A1),A1 ; A1 = used_queue (pointer to usedQ)
- _Enqueue ; put the PacketBuffer in the usedQ
-
- GetNextBuffer:
- LEA free_queue,A1 ; A1 = ^free_queue
- MOVE.L (A1),A1 ; A1 = free_queue (pointer to freeQ)
- LEA current_qelem, A0 ; copy freeQ.qHead into current_qelem
- MOVE.L qHead(A1),(A0)
- MOVEA.L qHead(A1),A0 ; A0 = freeQ.qHead
- _Dequeue
-
- RcvRTS:
- RTS ; return to caller
- ENDP
-
- ;_________________________________________________________________________
- ; Function SL_InitSktListener(freeQ, usedQ: QHdrPtr): OSErr
- ;
- ;
-
- SL_InitSktListener PROC EXPORT
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result1 DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- freeQ DS.L 1 ; freeQ parameter
- usedQ DS.L 1 ; usedQ parameter
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; placeholder for return address
- A6Link DS.L 1 ; placeholder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame,QHdr ; use these record types
-
- LINK A6,#LocalSize ; allocate our local stack frame
-
- ; copy the queue header pointers into our local storage for use in the listener
-
- LEA used_queue,A0 ; copy usedQ into used_queue
- MOVE.L usedQ(A6),(A0)
-
- LEA free_queue,A0 ; copy freeQ into free_queue
- MOVE.L freeQ(A6),(A0)
-
- ; dequeue the first buffer record from freeQ and set current_qelem to it
-
- MOVEA.L freeQ(A6),A1 ; A1 = ^freeQ
- LEA current_qelem, A0 ; copy freeQ.qHead into current_qelem
- MOVE.L qHead(A1),(A0)
- MOVEA.L qHead(A1),A0 ; A0 = freeQ.qHead
- _Dequeue
- MOVE.W D0,Result1(A6) ; Return status
-
- @1 UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
- ENDP
-
- ;--------------------------------------
- ; myVBLSpinInstall
- ;
- ; 10/90 pvh
- ;
- ; I hated the ToolLib spinning cursor routines enough to make up my own. Those routines
- ; are fine if you base your spinning cursor off a tight loop where you can continuously call the
- ; routines to actually spin the cursor. In my case that library was not ideal, so instead
- ; I just threw ('slapped' might be the better term) together a VBL task that spins the cursor
- ; instead (ala MacApp).
- ;
- ; This routine & the clean up routine that follows are pretty mcuh self explanatory. 4 cursors
- ; are preloaded & locked so they'll be sure to be available when the VBL task is called. The
- ; task is set up and moved into the application's heap. The task itself checks a locally saved
- ; variable for the cursor ID, loads in that cursor and sets that cursor as the current one if
- ; the cursor state is not currently busy (by checking CrsrBusy).
- ;
- ; When the task finishes, global references to the VBL task are used in the clean up routine
- ; (stopAndRemoveSpinningCursor) to remove the task & associated buffers. The cursors are also
- ; released from memory here.
- ;
- ; 10/16/90 pvh
- ;
- ; gMac was imported originally to help support color cursors within this task, but that endeavor
- ; was turning out to be too much of a hack (even for me), so it's staying around as a remanant of
- ; that failed attempt just to mark another one of my failures. :-)
-
- spinGlobals RECORD 0 ; this is our global data storage
- gtheTaskPtr DS.L 1 ; pointer to hold task itself
- gtheVBLPtr DS.L 1 ; pointer for VBL task record
- ENDR
-
- EXPORT (sg):DATA
-
- sg DS spinGlobals ; globals for spin cursor
-
-
- myVBLSpinInstall PROC EXPORT
- IMPORT gMac : DATA
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start listing parameters here
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- taskSize DS.L 1 ; size of our VBL task
- curses DS.L 4 ; handle for our cursor
- cursType DS.L 1
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame, SysEnvRec ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- ; pre-load in the resources to make sure they are around
- CLR.L -(sp) ; make space on the stack for result
- MOVE.L #'CURS', cursType(a6) ; another remanant from color stuff (don't ask)
- MOVE.L cursType(a6), -(sp)
- MOVE #1001, -(sp)
- _GetResource
- MOVE.L (sp)+, curses(a6)
- MOVE.L curses(a6), a0
- _HLock
-
- CLR.L -(sp) ; make space on the stack for result
- MOVE.L cursType(a6), -(sp)
- MOVE #1002, -(sp)
- _GetResource
- MOVE.L (sp)+, curses+4(a6)
- MOVE.L curses+4(a6), a0
- _HLock
-
- CLR.L -(sp) ; make space on the stack for result
- MOVE.L cursType(a6), -(sp)
- MOVE #1003, -(sp)
- _GetResource
- MOVE.L (sp)+, curses+8(a6)
- MOVE.L curses+8(a6), a0
- _HLock
-
- CLR.L -(sp) ; make space on the stack for result
- MOVE.L cursType(a6), -(sp)
- MOVE #1004, -(sp)
- _GetResource
- MOVE.L (sp)+, curses+12(a6)
- MOVE.L curses+12(a6), a0
- _HLock
-
- BRA.S theTaskEnd
-
- ; actual VBL Task
- theTaskBegin
- MOVEM.L a0-a6/d0-d7, -(sp) ; save
- BRA.S afterStorage
- A5Storage
- DC.L 0
- afterStorage
- ; reset the vbl count
- MOVE.W #5, vblCount(a0)
-
- ; restore A5 for globals we may have
- LEA A5Storage, a0
- MOVE.L (a0), a5
- BRA.S xxx
- cursorStorage
- DC.W $03E9 ; storage for cursor type, start with first cursor ID
- xxx
- LEA cursorStorage, a0
- ADD.W #1, (a0)
- MOVE.W (a0), d0
- CMP.W #1005, d0
- BLT.S doCursor
-
- MOVE.W #1001, (a0) ; start over with cursor type #1001
- MOVE.W #1001, d0 ; it needs to be in d0
- doCursor
- CLR.L -(a7) ; make some space for return
- MOVE.W d0, -(a7) ; move in cursor type
- _GetCursor
- MOVE.L (a7)+, a0 ; move handle into a0
- BEQ.S vblExit ; test for nil handle
- tst.b CrsrBusy ; cursor drawing as we speak? then split.
- BNE.S vblExit
- MOVE.L (a0), -(a7) ; deref and push on stack
- _SetCursor
- vblExit
- MOVEM.L (sp)+, a0-a6/d0-d7 ; restore
- rts
- theTaskEnd
-
- ; VBL initialization code
- LEA theTaskEnd, a0 ; address of tail of task
- LEA theTaskBegin, a1 ; head of task
- MOVE.L a0, d0 ; get size of task
- SUB.L a1, d0
- MOVE.L d0, taskSize(a6)
-
- LEA A5Storage, a0 ; put current A5 into our storage area in code
- MOVE.L CurrentA5, (a0)
-
- ; set up VBL record
- MOVE.L #vblPhase+2, d0 ; size of VBLTask
- _NewPtr
- MOVE.L a0, sg.gtheVBLPtr(a5)
-
- ; setup block of memory to hold task itself (in our heap, not the System heap)
- MOVE.L taskSize(a6), d0
- _NewPtr
- MOVE.L a0, sg.gtheTaskPtr(a5)
-
- ; move the task code into block in heap
- LEA theTaskBegin, a0 ; head of task
- MOVE.L sg.gTheTaskPtr(a5), a1
- MOVE.L taskSize(a6), d0
- _BlockMove
-
- MOVE.L sg.gtheTaskPtr(a5), a1
- MOVE.L sg.gtheVBLPtr(a5), a0
- MOVE.L a1, vblAddr(a0) ; a1 contains address of moved TheTask
- MOVE.W #vType, qType(a0)
- MOVE.W #10, vblCount(a0)
- MOVE.W #4, vblPhase(a0) ; whatever
- _VInstall
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- ENDP
-
- ;--------------------------------------
- ; this routine disposes of the VBL spinning cursor task & removes memory allocated for the
- ; task. also unloads the cursors from the heap.
-
- stopAndRemoveSpinningCursor PROC EXPORT
-
- IMPORT gtheTaskPtr : DATA
- IMPORT gtheVBLPtr : DATA
-
- MOVE.L sg.gtheVBLPtr, a0
- _VRemove
-
- MOVE.L sg.gtheVBLPtr, a0
- _DisposPtr
-
- MOVE.L sg.gtheTaskPtr, a0
- _DisposPtr
-
- ; unload the cursors
- CLR.L -(sp)
- MOVE.L #'CURS', -(sp)
- MOVE #1001, -(sp)
- _GetResource
- _ReleaseResource
-
- CLR.L -(sp)
- MOVE.L #'CURS', -(sp)
- MOVE #1002, -(sp)
- _GetResource
- _ReleaseResource
-
- CLR.L -(sp)
- MOVE.L #'CURS', -(sp)
- MOVE #1003, -(sp)
- _GetResource
- _ReleaseResource
-
- CLR.L -(sp)
- MOVE.L #'CURS', -(sp)
- MOVE #1004, -(sp)
- _GetResource
- _ReleaseResource
-
- rts
-
- ENDP
- ;--------------------------------------
- END ; end of this source file
-